import json
from typing import Any, Dict, Optional

from fastapi.encoders import jsonable_encoder
from starlette.responses import HTMLResponse
from typing_extensions import Annotated, Doc

swagger_ui_default_parameters: Annotated[
    Dict[str, Any],
    Doc(
        """
        Default configurations for Swagger UI.

        You can use it as a template to add any other configurations needed.
        """
    ),
] = {
    "dom_id": "#swagger-ui",
    "layout": "BaseLayout",
    "deepLinking": True,
    "showExtensions": True,
    "showCommonExtensions": True,
}


def get_swagger_ui_html(
    *, 
    openapi_url: str,
    title: str,
    swagger_js_url: str = "/static/swagger-ui/swagger-ui-bundle.js",
    swagger_css_url: str = "/static/swagger-ui/swagger-ui.css",
    swagger_favicon_url: str = "/static/swagger-ui/favicon-32x32.png",
    oauth2_redirect_url: Optional[str] = None,
    init_oauth: Optional[Dict[str, Any]] = None,
    swagger_ui_parameters: Optional[Dict[str, Any]] = None,
) -> HTMLResponse:
    current_swagger_ui_parameters = swagger_ui_default_parameters.copy()
    if swagger_ui_parameters:
        current_swagger_ui_parameters.update(swagger_ui_parameters)

    # 构建SwaggerUIBundle配置
    config = {
        'url': openapi_url,
    }
    config.update(current_swagger_ui_parameters)
    if oauth2_redirect_url:
        config['oauth2RedirectUrl'] = f"window.location.origin + '{oauth2_redirect_url}'"

    # 转换为JSON字符串，确保没有多余的逗号
    config_json = json.dumps(config, indent=4)
    # 替换双引号为单引号，以便在HTML中正确嵌入
    config_json = config_json.replace('"', '\'')

    # 正确构建HTML内容
    html = (
        '<!DOCTYPE html>\n'
        '<html>\n'
        '<head>\n'
        '<link type="text/css" rel="stylesheet" href="' + swagger_css_url + '">\n'
        '<link rel="shortcut icon" href="' + swagger_favicon_url + '">\n'
        '<title>' + title + '</title>\n'
        '</head>\n'
        '<body>\n'
        '<div id="swagger-ui"></div>\n'
        '<script src="' + swagger_js_url + '"></script>\n'
        '<script>\n'
        'const ui = SwaggerUIBundle({\n'
        + config_json + ',\n'
        'presets: [\n'
        '    SwaggerUIBundle.presets.apis,\n'
        '    SwaggerUIBundle.SwaggerUIStandalonePreset\n'
        ']\n'
        '})\n'
    )
"""

    if init_oauth:
        html += f"""
        ui.initOAuth({json.dumps(jsonable_encoder(init_oauth))})
"""

    html += """
    </script>
    </body>
    </html>
    """
    return HTMLResponse(html)